﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;
using FTTXImportUtility.Utility;
using System.Collections;
using System.Threading;

namespace FTTXImportUtility
{
  public partial class MainForm : Form
  {
    private SPSite _sourceSite;
    private SPWeb _sourceWeb;
    private SPSite _targetSite;
    private SPWeb _targetWeb;
    private FormMap _formMapping;
    private Hashtable _roadMap;
    //private bool _sourceListChanged = false;
    //private bool _targetListChanged = false;

    public MainForm()
    {
      InitializeComponent();
    }

    #region Events

    private void buttonCopy_Click(object sender, EventArgs e)
    {
      if (_roadMap == null || (_roadMap != null && _roadMap.Count == 0))
      {
        this.ShowMessageInformation("Edit mapping");
        this.buttonEditMap.Focus();
        return;
      }

      if (checkBoxCopy.Checked && checkBoxCopy.Enabled)
      {
        CopyItems();

      }
      else
      {
        AddItems();
      }
    }

    private void buttonGo_Click(object sender, EventArgs e)
    {
      try
      {
        GetLists(ref this._sourceSite, ref this._sourceWeb, this.SourceSiteAddress, this.comboBoxListsSource);
        if (checkBoxSame.Checked)
        {
          this.comboBoxTargetAddress.Text = this.comboBoxSourceAddress.Text;
          this.button2Go_Click(this.button2Go, new EventArgs());
        }
      }
      catch (Exception ex)
      {
        this.ShowMessageError(ex.Message);
      }
    }

    private void button2Go_Click(object sender, EventArgs e)
    {
      try
      {
        GetLists(ref this._targetSite, ref this._targetWeb, this.TargetSiteAddress, this.comboBoxListsTarget);
      }
      catch (Exception ex)
      {
        this.ShowMessageError(ex.Message);
      }
    }

    private void buttonEditMap_Click(object sender, EventArgs e)
    {
      if (_formMapping == null)
      {
        _formMapping = new FormMap(this.SourceList, this.TargetList);
      }

      if (checkBoxRefresh.Checked)
      {
        _formMapping.SetSources(SourceList, TargetList);
        this.listBoxMapping.Items.Clear();
      }

      if (_formMapping.ShowDialog() == DialogResult.OK)
      {

        RoadMap = _formMapping.RoadMap;
      }
    }

    private void buttonDefault_Click(object sender, EventArgs e)
    {
      RoadMap = AlgorithmDefaultUtility.GetDefaultRoadMap(TargetList, SourceList);
    }

    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
      SetStatus("Closing sites");
      if (_sourceSite != null)
        _sourceSite.Dispose();
      if (_sourceWeb != null)
        _sourceWeb.Dispose();
      if (_targetSite != null)
        _targetSite.Dispose();
      if (_targetWeb != null)
        _targetWeb.Dispose();

      Done();
    }

    private void checkBoxCopy_CheckedChanged(object sender, EventArgs e)
    {
      if (checkBoxCopy.Checked)
      {
        if (this.TargetList != null && this.SourceList != null && this.TargetList.ID != this.SourceList.ID)
        {
          this.ShowMessageInformation("Cannot copy. Source and target list must be the same");
          this.checkBoxCopy.Checked = false;
          return;
        }
      }
    }

    private void buttonDelete_Click(object sender, EventArgs e)
    {
      if (string.IsNullOrEmpty(comboBoxSourceListDelete.Text))
      {
        this.ShowMessageInformation("Select list");
        return;
      }
      if (MessageBox.Show(this, "Are you sure ?", this.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
      {

        this.toolStripProgressBar1.Visible = true;
        this.Enabled = false;
        SetStatus("Start to delete...");

        try
        {
          using (SPSite site = new SPSite(comboBoxAddressDelete.Text))
          {
            using (SPWeb web = site.OpenWeb())
            {
              var i = 1;

              SPList list = web.Lists[comboBoxSourceListDelete.Text];

              var count = list.ItemCount;

              this.toolStripProgressBar1.Maximum = count;

              for (int n = list.ItemCount; --n >= 0; )
              {
                Application.DoEvents();
                this.toolStripProgressBar1.Value = i;

                SetStatus(string.Format("Deleting item {0} ...", i++));

                list.Items[n].Delete();
              }
            }
          }
        }
        catch (Exception ex)
        {
          this.ShowMessageError(ex.Message);
        }
        finally
        {
          this.toolStripProgressBar1.Visible = false;
          this.toolStripProgressBar1.Value = 0;
          this.Enabled = true;
        }
      }
      Done();
    }

    private void button3Go_Click(object sender, EventArgs e)
    {
      SetStatus("Open site...");
      try
      {
        using (SPSite site = new SPSite(comboBoxAddressDelete.Text))
        {
          using (SPWeb web = site.OpenWeb())
          {
            SetStatus("Retrinving data");
            comboBoxSourceListDelete.SetDataSource(web.Lists);
          }
        }
      }
      catch (Exception ex)
      {
        this.ShowMessageError(ex.Message);
      }
      Done();
    }

    private void comboBoxList_SelectedIndexChanged(object sender, EventArgs e)
    {
      checkBoxCopy.Enabled = (!string.IsNullOrEmpty(comboBoxListsSource.Text)
          && !string.IsNullOrEmpty(comboBoxListsTarget.Text))
          && (comboBoxListsTarget.Text == comboBoxListsSource.Text);
      this.EnableDisable((!string.IsNullOrEmpty(comboBoxListsSource.Text)
          && !string.IsNullOrEmpty(comboBoxListsTarget.Text)), new Control[]{ 
                this.buttonEditMap,
                this.buttonDefault,
                this.checkBoxRefresh});
    }

    private void checkBoxCopy_EnabledChanged(object sender, EventArgs e)
    {
      if (!(sender as CheckBox).Enabled)
      {
        checkBoxCopy.Checked = false;
      }
    }

    private void checkBoxSame_CheckedChanged(object sender, EventArgs e)
    {
      if (checkBoxSame.Checked)
      {
        this.EnableDisable(false, new Control[]{
                    this.label4,
                    this.comboBoxTargetAddress,
                    this.button2Go
                });
      }
      else
      {
        this.EnableDisable(true, new Control[]{
                    this.label4,
                    this.comboBoxTargetAddress,
                    this.button2Go
                });
      }
    }


    #endregion

    #region Utils

    private void CopyItems()
    {
      var i = 0;

      try
      {
        StartJob(SourceList.Items.Count);

        foreach (var targetKey in RoadMap.Keys)
        {
          ItemTag itemTag = (ItemTag)RoadMap[targetKey];

          SPField spField = SourceList.Fields[itemTag.SourceField.Id];

          MessageBox.Show(spField.TypeAsString);

          MessageBox.Show(((spField is SPFieldLookup) ? "is SPFieldLookup" : "is not SPFieldLookup"));

          //(sourceItem.Fields[itemTag.SourceField.Id] is SPFieldLookup)
          //
        }


        foreach (SPListItem sourceItem in SourceList.Items)
        {
          i++;
          SetStatus("Update item {0}...", i);
          this.toolStripProgressBar1.Value = i;

          foreach (var targetKey in RoadMap.Keys)
          {
            ItemTag itemTag = (ItemTag)RoadMap[targetKey];

            if (itemTag.SourceField is SPFieldLookup && itemTag.ExtractTextOnlyFromLookUp)
            {
              Object value = sourceItem[itemTag.SourceField.Id];
              sourceItem[itemTag.TargetField.Id] = (value != null) ? this.GetValueFromLookupField(value.ToString()): value;
            }
            else
              sourceItem[itemTag.TargetField.Id] = sourceItem[itemTag.SourceField.Id];

            sourceItem.Update();
            Application.DoEvents();
          }

        }
      }
      finally
      {
        EndJob(i);
      }
    }

    private void AddItems()
    {
      var i = 0;

      try
      {
        SetStatus("Start copying...");

        this.StartJob(SourceList.Items.Count);

        foreach (SPListItem sourceItem in SourceList.Items)
        {
          i++;
          SetStatus("Copying item {0}...", i);
          this.toolStripProgressBar1.Value = i;


          SPListItem copyItem = TargetList.Items.Add();

          foreach (var targetKey in RoadMap.Keys)
          {
            ItemTag itemTag = (ItemTag)RoadMap[targetKey];

            if (itemTag.SourceField is SPFieldLookup && itemTag.ExtractTextOnlyFromLookUp)
            {
              Object value = sourceItem[itemTag.SourceField.Id];
              copyItem[itemTag.TargetField.Id] = (value != null) ? this.GetValueFromLookupField(value.ToString()) : value;
            }
            else
              copyItem[itemTag.TargetField.Id] = sourceItem[itemTag.SourceField.Id];
                        

            copyItem.Update();
            Application.DoEvents();
          }

          copyItem.Update();
          Application.DoEvents();


        }
      }
      finally
      {
        EndJob(i);
      }
    }

    private void EndJob(int count)
    {
      _targetWeb.AllowUnsafeUpdates = false;
      this.toolStripProgressBar1.Visible = false;
      this.toolStripProgressBar1.Value = 0;
      Done();
      this.Enabled = true;
      this.ShowMessage("Copied " + count, "Done");
    }

    private void StartJob(int maximum)
    {
      _targetWeb.AllowUnsafeUpdates = true;
      this.toolStripProgressBar1.Visible = true;
      this.toolStripProgressBar1.Maximum = maximum;
      this.statusStrip1.Update();
      this.Enabled = false;
    }

    private string GetValueFromLookupField(string itemText)
    {
      var len = itemText.Length;
      var index = itemText.IndexOf("#");
      return itemText.Substring(index + 1, len - index - 1);
    }

    private void SetStatus(string formatString, params object[] objects)
    {
      var str = new StringBuilder(formatString);

      for (int i = 0; i < objects.Length; i++)
      {
        var t = string.Format("{{0}}", i);

        str.Replace(t, objects[i].ToString());
      }

      this.SetStatus(str.ToString());
    }

    private void GetLists(ref SPSite site, ref SPWeb web, string siteAddress, ComboBox control)
    {
      site = new SPSite(siteAddress);

      SetStatus("Open site...");

      web = site.OpenWeb();

      SetStatus("Get site lists...");

      control.SetDataSource(web.Lists, "Title", "ID", false);

      Done();
    }

    private void SetStatus(string status)
    {
      this.toolStripStatusLabel1.Text = status;
      this.statusStrip1.Update();
    }

    private void Done()
    {
      SetStatus("Done!");
    }

    private void EnableDisable(bool flag, Control[] controls)
    {
      foreach (var control in controls)
      {
        control.Enabled = flag;
      }
    }

    #endregion

    #region Properties

    protected string SourceSiteAddress
    {
      get
      {
        return this.comboBoxSourceAddress.Text;
      }
    }

    protected string TargetSiteAddress
    {
      get
      {
        return this.comboBoxTargetAddress.Text;
      }
    }

    protected string SourceListName
    {
      get
      {
        return comboBoxListsSource.Text;
      }
    }

    protected string TargetListName
    {
      get
      {
        return comboBoxListsTarget.Text;
      }
    }

    protected SPList SourceList
    {
      get
      {
        try
        {
          return _sourceWeb.Lists[this.SourceListName];
        }
        catch
        {
          if (_sourceWeb == null)
            this.ShowMessageInformation("Select source site and click \"Go\" button");
          if (string.IsNullOrEmpty(this.SourceListName))
            this.ShowMessageInformation("Select source list");

          return null;
        }
      }
    }

    protected SPList TargetList
    {
      get
      {
        try
        {
          return _targetWeb.Lists[this.TargetListName];
        }
        catch
        {
          if (_targetWeb == null)
            this.ShowMessageInformation("Select target site and click \"Go\" button");
          if (string.IsNullOrEmpty(this.TargetListName))
            this.ShowMessageInformation("Select target list");

          return null;
        }
      }
    }

    protected Hashtable RoadMap
    {
      set
      {
        this._roadMap = value;
        this.listBoxMapping.Items.Clear();
        foreach (var item in value.Keys)
        {
          //var str = string.Format("{0}- >{1}", value[item].ToString(), item);
          //this.listBoxMapping.Items.Add(str);
          this.listBoxMapping.Items.Add(value[item]);
        }
      }
      get
      {
        return _roadMap;
      }
    }

    #endregion

  }
}